#include "ti_msp_dl_config.h"
#include "usart_openmv.h"

uint8_t mvbuf[10] = {0,0,0,0,0,0,0,0,0,0};


uint8_t calc_checksum(uint8_t *buf, uint8_t size)
{
    uint8_t checksum = 0;
    for (uint8_t i = 0; i < size; i++) {
        checksum ^= buf[i]; // 改为异或
    }
    return checksum;
}

// 向OpenMV发送包
void uart_ex_send(uint8_t size,uint8_t *data)
{

		data_bag_t  databag={
		.header=0x2321,//#！
		.size=size,
		.data=data,
		.checksum=calc_checksum(data,size)	
		};

		DL_UART_transmitData(UART_OPENMV_INST,databag.header & 0xFF);
		DL_UART_transmitData(UART_OPENMV_INST,databag.header>>8);
		DL_UART_transmitData(UART_OPENMV_INST,databag.size);
		for (uint32_t i=0;i<databag.size;i++)
		{
		DL_UART_transmitData(UART_OPENMV_INST,databag.data[i]);			
		}
		DL_UART_transmitData(UART_OPENMV_INST,databag.checksum);
}

// 接受OpenMV的包
void uart_ex_recv(void){

			if (data_ready_flag != 1) {
				return;
			}

			if (((uart_temp[0] == 0x21) && (uart_temp[1] == 0x23)) == 0) {
				data_ready_flag = 0; // 包头错误标志置0 让中断继续
            	return;
            }
			
			uint8_t data_size = uart_temp[2];

			// 接收数据部分
			uint8_t buf_temp[6];
			for (uint8_t i = 0; i < 6; i++) {
				buf_temp[i] = uart_temp[3 + i];
			}
			// 接收校验和
            uint8_t checksum= uart_temp[9];
			

            // 数据转移完毕开始校验
            if (checksum != calc_checksum(buf_temp, data_size)) {
				data_ready_flag = 0; // 数据就绪标志置0 让中断继续
                return;  // 校验失败，丢弃数据
            }

            // 校验成功，接收数据
            for (uint8_t i = 0; i < 6; i++) {
                mvbuf[i] = buf_temp[i];
            }

			data_ready_flag = 0; // 数据就绪标志置0 让中断继续
			return;
}

// 调试时，向VOFA+发送字符
void uart_debug_send_char(char ch)
{
    //当串口0忙的时候等待，不忙的时候再发送传进来的字符
    while (DL_UART_isBusy(UART_OPENMV_INST) == true);
    //发送单个字符
    DL_UART_Main_transmitData(UART_OPENMV_INST, ch);
}

// 调试时，向VOFA+发送字符串
void uart_debug_send_string(char* str)
{
    //当前字符串地址不在结尾 并且 字符串首地址不为空
    while (*str != 0 && str != 0)
    {
        //发送字符串首地址中的字符，并且在发送完成之后首地址自增
        uart_debug_send_char(*str++);
    }
}



//重定向fputc函数
int fputc(int c, FILE* stream)
{
    DL_UART_Main_transmitDataBlocking(UART_OPENMV_INST, c);
    return c;
}

int fputs(const char* restrict s, FILE* restrict stream)
{
    uint16_t i, len;
    len = strlen(s);
    for (i = 0; i < len; i++)
    {
        DL_UART_Main_transmitDataBlocking(UART_OPENMV_INST, s[i]);
    }
    return len;
}

int puts(const char* _ptr)
{
    int count = fputs(_ptr, stdout);
    count += fputs("\n", stdout);
    return count;
}
